﻿using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Sockets;
using NLog;

namespace MailServer
{
    class MailServer : IMailServer
    {
        private readonly TcpListener _listener;
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();
        private CancellationTokenSource _cancellationTokenSource;

        public MailServer(int port)
        {
            _cancellationTokenSource = new CancellationTokenSource();
            _listener = new TcpListener(IPAddress.Any, port);
        }

        /// <summary>
        /// Start MailServer
        /// </summary>
        public void Start()
        {
            _logger.Info("Server Started");
            _listener.Start();
            try
            {
                while (true)
                {
                    if (!_listener.Pending())
                    {
                        if (_cancellationTokenSource.Token.IsCancellationRequested)
                        {
                            break;
                        }
                        Thread.Sleep(500);
                        continue;
                    }

                    var client = _listener.AcceptTcpClient();
                    Task.Factory.StartNew(() => ClientThread(client));
                }
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
            }
        }

        public void Stop()
        {
            if (_listener != null)
                _cancellationTokenSource.Cancel(false);
            _logger.Info("Server Stoped");
        }

        private void ClientThread(TcpClient client)
        {
            // ReSharper disable ObjectCreationAsStatement
            new ClientConnectionHandler(client);
            // ReSharper restore ObjectCreationAsStatement
        }
    }
}
